home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part2 / 12440 < prev    next >
Encoding:
Internet Message Format  |  1996-08-05  |  3.7 KB

  1. Path: druid.borland.com!usenet
  2. From: pete@borland.com (Pete Becker)
  3. Newsgroups: comp.lang.c++
  4. Subject: Re: Implicit Typecasting
  5. Date: 20 Mar 1996 00:21:57 GMT
  6. Organization: Borland International
  7. Message-ID: <4inj35$qcp@druid.borland.com>
  8. References: <1996Mar16.203628.15187@mcs.drexel.edu>
  9. NNTP-Posting-Host: pbecker.borland.com
  10. Mime-Version: 1.0
  11. Content-Type: Text/Plain; charset=ISO-8859-1
  12. X-Newsreader: WinVN 0.99.5
  13.  
  14. In article <1996Mar16.203628.15187@mcs.drexel.edu>, ucphinni@mcs.drexel.edu 
  15. says...
  16. >
  17. >        I am trying to write a personalized C++ library using Codewarrior on 
  18. the
  19. >Mac platform (the type of platform should not matter.  My main concern is
  20. >portability, followed closely by speed.).
  21. >        The library is going to have all of the basic structures such as a
  22. >linked list node, different types of stacks, different types of trees,
  23. >...etc... and some higher order classes, like scheduling algorithms. I
  24. >have had some success, but there is one nagging question that has been
  25. >bothering me.
  26. >        In many of my classes, I use inheritence and must change the interface
  27. >so the client need not worry about the implementation details (standard c++
  28. >practice) about the interface.  For example, in one part of my library, I
  29. >have something like this:
  30. >
  31. >class llNode {
  32. >        typedef llNode ll;
  33. >        public:
  34. >                llNode(ll * anext = NULL) { nextptr = anext;}
  35. >                ll * next(void) { return nextptr;}
  36. >                ll * next(ll * anext) { return nextptr = anext;}
  37. >                ... cut code ...
  38. >        private:
  39. >                ll * nextptr;
  40. >};
  41. >
  42. >class dlNode : public llNode {
  43. >        typedef dlNode dl;
  44. >        public:
  45. >                dlNode(dl * aprev = NULL,dl * anext = NULL) : ll((ll *) anext)
  46. >                { prevptr = aprev;}
  47. >                dl * prev(void) { return (dl *) prevptr.next();}
  48. >                dl * prev(dl * aprev) { return (dl *) prevptr.next((dl *) 
  49. aprev);}
  50. >                dl * next(void) { return (dl *) ll::next();}
  51. >                dl * next(dl * anext) { return (dl *) ll::next((ll *) anext);}
  52. >                }
  53. >        private:
  54. >                ll prevptr;
  55. >};
  56. >
  57. >        My question is of a readability more than a functionality concern.    
  58.   For
  59. >the above code, it would seem to me that a lot of meaningless code (just
  60. >typecasting) is being done.      Is there any standard way to eliminate this.
  61. >In other words, is there a way for the compiler to automatically equate the
  62. >current class to the superclass and compile it without any warnings (i.e.
  63. >compiler would replace ll for dl in the abovemented case)  In the previous
  64. >case, this would elimate all of the public member functions in the dlNode.
  65.  
  66. Well, some of the casts aren't necessary. For instance:
  67.  
  68.     dlNode(dl * aprev = NULL,dl * anext = NULL) : ll((ll *) anext)
  69.  
  70. can be written just as well without the cast:
  71.  
  72.     dlNode(dl * aprev = NULL,dl * anext = NULL) : ll(anext)
  73.  
  74. Other casts are necessary, but dangerous. For example:
  75.  
  76.     dl * prev(void) { return (dl *) prevptr.next();}
  77.  
  78. The cast here is necessary, because prevptr.next() returns an ll*, not a dl*. 
  79. However, the cast is not safe: it is entirely possible to use this class in a 
  80. way that results in the actual type being a pointer to ll, not a pointer to dl:
  81.  
  82.     llNode Node;
  83.     dlNode DNode;
  84.     DNode.llNode::next(Node);
  85.  
  86. now the nextptr in DNode holds a pointer to an llNode, and calling DNode.next() 
  87. results in a bogus pointer. This can be fixed by making llNode a private base 
  88. or by using it as a member rather than a base. Once you've done that, the 
  89. casts are indeed necessary. When you can prove to yourself that there is no 
  90. code path that can result in getting the wrong type of pointer back you can 
  91. feel safe about the use of the casts.
  92.     -- Pete
  93.  
  94.